<?php

namespace app\controller\admin\exam;

use app\model\admin\User;
use app\model\Category;
use app\model\Course;
use app\model\Exam;
use app\model\Exam\Papers as PapersModel;
use \app\model\exam\PaperQuestions;
use app\model\Org;
use app\model\Questions;
use app\service\admin\GenerateWord;
use laytp\controller\Backend;
use think\facade\Config;
use laytp\library\CommonFun;
use app\service\admin\UserServiceFacade;

use PhpOffice\PhpWord\PhpWord;
use PhpOffice\PhpWord\SimpleType\Jc;
use PhpOffice\PhpWord\Style\Font;
/**
 * 试卷管理
 */
class Papers extends Backend
{

    const SINGLE_NUM = 15;
    const MULTIPLE_NUM = 15;
    const JUDGE_NUM = 10;
    const SUBJECT_NUM = 2;
    /**
     * exam_papers模型对象
     * @var \app\model\exam\Papers
     */
    protected $model;
	protected $hasSoftDel=0;//是否拥有软删除功能

    protected $noNeedLogin = []; // 无需登录即可请求的方法
    protected $noNeedAuth = ['index', 'info']; // 无需鉴权即可请求的方法

    public function _initialize()
    {
        $this->model = new \app\model\exam\Papers();
    }

    
    //查看和搜索列表
    public function index(){
        $where  = $this->buildSearchParams();
        $order  = $this->buildOrder();

        $orgId = UserServiceFacade::getUser()->org_id;
        if (!in_array($orgId, $this->allAllowOrgIds))
        {
            $where['org_id'] = $orgId;
        }

        $data   = $this->model->where($where)->order($order);
        $paging = $this->request->param('paging', false);
        if ($paging) {
            $limit        = $this->request->param('limit', Config::get('paginate.limit'));
            $data         = $data->paginate($limit)->toArray();
            $data['data'] = $this->getSelectedData($data['data']);
        } else {
            $data = $data->select()->toArray();
        }


        $adminUserList = User::where('status', ">=", '0')->column('nickname', 'id');
        $courseList = \app\model\Course::where('status', 1)->column('name', 'id');
        $categoryList = \app\model\Category::where('status', 1)->column('name', 'id');

        if (isset($data['data'])) {
            foreach ($data['data'] as &$row) {
                $row['user_name'] = $adminUserList[$row['user_id']] ?? '';
                $row['category_name'] = $categoryList[$row['category_id']] ?? '';
                $row['course_name'] = $courseList[$row['course_id']] ?? '';

            }
        }
        return $this->success('数据获取成功', $data);
    }

    
    //添加
    public function add()
    {
        $post = CommonFun::filterPostData($this->request->post());
		$post['user_id'] = UserServiceFacade::getUser()->id;
        try {
            if ($this->model->create($post)) {
                return $this->success('添加成功', $post);
            } else {
                return $this->error('操作失败');
            }
        } catch (\Exception $e) {
            return $this->exceptionError($e);
        }
    }

    
    //查看详情
    public function info()
    {
        $id   = $this->request->param('id');
        $info = $this->model->find($id);
        return $this->success('获取成功', $info);
    }

    
    //编辑
    public function edit(){
        $id = $this->request->param('id');
        $info = $this->model->find($id);
        $post = CommonFun::filterPostData($this->request->post());
		$post['user_id'] = UserServiceFacade::getUser()->id;
        foreach ($post as $k => $v) {
            $info->$k = $v;
        }
        try {
            $updateRes = $info->save();
            if ($updateRes) {
                return $this->success('编辑成功');
            } else {
                return $this->error('操作失败');
            }
        } catch (\Exception $e) {
            return $this->exceptionError($e);
        }
    }

    
    public function delPaperQuestions()
    {
        $id = $this->request->param('id');
        if (!$id) {
            return $this->error('参数id不能为空');
        }
        $paperQuestionsModel = new PaperQuestions();
        $row = $paperQuestionsModel->where('id', $id)->find();
        if (is_null($row))
            return $this->error('数据不存在');
        $papersModel = new PapersModel();
        $paperInfo = $papersModel->where('id', $row->paper_id)->column('status', 'id');

        if (isset($paperInfo[$row->paper_id]) && $paperInfo[$row->paper_id] == 1)
            return $this->error('试卷已发布，不能删除试题');

        $deleteRes = $paperQuestionsModel->where('id', $id)->delete();
        if (!is_numeric($deleteRes))
            return $this->error('操作失败');


        return $this->success('删除成功');

    }
    
    //设置状态
    public function setStatus()
    {
        $id       = $this->request->post('id');
        $fieldVal = $this->request->post('field_val');
        $isRecycle = $this->request->post('is_recycle');
        $update['status'] = $fieldVal;
        try {
            if($isRecycle) {
                $updateRes = $this->model->onlyTrashed()->where('id', '=', $id)->update($update);
            } else {
                $updateRes = $this->model->where('id', '=', $id)->update($update);
            }
            if ($updateRes) {
                return $this->success('操作成功');
            } else if ($updateRes === 0) {
                return $this->success('未作修改');
            } else {
                return $this->error('操作失败');
            }
        } catch (\Exception $e) {
            return $this->error('数据库异常，操作失败');
        }
    }


    public function addQuestions()
    {
        $post = CommonFun::filterPostData($this->request->post());

        if ($post['paper_id'] <= 0){
            return $this->error('请选择试卷');
        }
        if (empty($post['ids'])){
            return $this->error('请选择组卷试题');
        }
        $post['user_id'] = UserServiceFacade::getUser()->id;
        $model = new PaperQuestions();

        $data = [];
        foreach(explode(',', $post['ids']) as $val) {
            $info = $model->where(['paper_id' => $post['paper_id'], 'question_id' => $val])->find();
            if (!is_null($info))
                continue;

            $data[] = [
                'paper_id'      => $post['paper_id'],
                'question_id'   => $val,
                'user_id'       => $post['user_id'],
                'score'         => $val['score'] ?? 0,
                'sort'          => $val['sort'] ?? 0,
            ];
        }

        try {
            if ($model->saveAll($data)) {
                return $this->success('添加成功', $post);
            } else {
                return $this->error('操作失败');
            }
        } catch (\Exception $e) {
            return $this->exceptionError($e);
        }

    }


    public function questionList()
    {
        $where  = $this->buildSearchParams();
        $order  = $this->buildOrder();
        $paperQuestionsModel = new PaperQuestions();
        $where['paper_id'] = $this->request->param('paper_id');

        $data   = $paperQuestionsModel->where($where)->order($order);
        $paging = $this->request->param('paging', false);
        if ($paging) {
            $limit        = $this->request->param('limit', Config::get('paginate.limit'));
            $data         = $data->paginate($limit)->toArray();
            $data['data'] = $this->getSelectedData($data['data']);
        } else {
            $data = $data->select()->toArray();
        }


        $adminUserList = User::where('status', ">=", '0')->column('nickname', 'id');
        $courseList = Course::where('status', ">=", "0")->column('name', 'id');
        $categoryList = Category::where('status', ">=", "0")->column('name', 'id');

        if (isset($data['data'])) {

            $questionIds = array_column($data['data'], 'question_id');
            $questionList = Questions::whereIn('id', $questionIds)
                ->column('title, type, difficulty, category_id, course_id', 'id');
            foreach ($data['data'] as &$row) {
                $row['user_name'] = $adminUserList[$row['user_id']] ?? '';
                $row['title'] = $questionList[$row['question_id']]['title'] ?? '';
                $row['type'] = $questionList[$row['question_id']]['type'] ?? '';
                $row['difficulty'] = $questionList[$row['question_id']]['difficulty'] ?? '';
                $row['course_name'] = $courseList[$questionList[$row['question_id']]['course_id']] ?? '';
                $row['category_name'] = $categoryList[$questionList[$row['question_id']]['category_id']] ?? '';
            }
        }
        return $this->success('数据获取成功', $data);
    }

    public function autoPaper()
    {
        $id = $this->request->param('id');
        if (!$id) {
            return $this->error('参数id不能为空');
        }
        $papersModel = new PapersModel();
        $paperInfo = $papersModel->where('id', $id)->find();
        if ($paperInfo && $paperInfo->status == 1)
            return $this->error('试卷已发布，不能自动生成试题');

        $paperQuestionsModel = new PaperQuestions();
        $row = $paperQuestionsModel->where('paper_id', $id)->find();

        if ($row)
            return $this->error('试卷已存在试题，不能自动生成试题');

        $categoryId = $paperInfo->category_id = 0;
        $courseId = $paperInfo->course_id = 0;
        #根据试卷所属的分类和课程自动生成试题
        // todo 暂时固定试题数量和类型， 非主观题每题2分， 主观题每题10分
        // todo 单选15题合计30分，多选15题合计30分，判断10合计20分，简答10题合计20分
        // todo 难易度，简单：中等：困难 6:2:2
        $questionModel = new Questions();
        if ($questionModel->where('status', 1)->where('type', 1)->count() < self::SINGLE_NUM) {
            return $this->error('题库单选题数量不足，请增加单选题');
        }

        if ($questionModel->where('status', 1)->where('type', 2)->count() < self::MULTIPLE_NUM) {
            return $this->error('题库多选题数量不足，请增加单选题');
        }
        if ($questionModel->where('status', 1)->where('type', 3)->count() < self::JUDGE_NUM) {
            return $this->error('题库判断题数量不足，请增加单选题');
        }
        if ($questionModel->where('status', 1)->where('type', 4)->count() < self::SUBJECT_NUM) {
            return $this->error('题库主观题数量不足，请增加单选题');
        }

        $orgId = UserServiceFacade::getUser()->org_id;
        #单选题
        $singleQuestions = $this->getSingleQuestions($questionModel, $categoryId, $courseId, $orgId);
        #多选题
        $multipleQuestions = $this->getMultipleQuestions($questionModel, $categoryId, $courseId, $orgId);
        #判断题
        $judgeQuestions = $this->getJudgeQuestions($questionModel, $categoryId, $courseId, $orgId);
        #主观题
        $subjectQuestions = $this->getSubjectQuestions($questionModel, $categoryId, $courseId, $orgId);

        $data = [];
        $i = 0;
        foreach ($singleQuestions as $val)
        {
            $i ++;
            $data[] = [
                'paper_id'      => $id,
                'question_id'   => $val,
                'user_id'       => UserServiceFacade::getUser()->id,
                'score'         => 2,
                'sort'          => $i,
            ];
        }
        foreach ($multipleQuestions as $val)
        {
            $i ++;
            $data[] = [
                'paper_id'      => $id,
                'question_id'   => $val,
                'user_id'       => UserServiceFacade::getUser()->id,
                'score'         => 2,
                'sort'          => $i,
            ];

        }

        foreach ($judgeQuestions as $val)
        {
            $i ++;
            $data[] = [
                'paper_id'      => $id,
                'question_id'   => $val,
                'user_id'       => UserServiceFacade::getUser()->id,
                'score'         => 2,
                'sort'          => $i,
            ];
        }

        foreach ($subjectQuestions as $val)
        {
            $i ++;
            $data[] = [
                'paper_id'      => $id,
                'question_id'   => $val,
                'user_id'       => UserServiceFacade::getUser()->id,
                'score'         => 10,
                'sort'          => $i,
            ];
        }

        $res = $paperQuestionsModel->saveAll($data);
        if (!$res)
        {
            return $this->error('组卷失败');
        }
        return $this->success('组卷成功', $paperInfo);

    }


    public function exportPaper()
    {


        $id = $this->request->param('id');
        if (!$id) {
            return $this->error('参数id不能为空');
        }
        $papersModel = new PapersModel();
        $paperInfo = $papersModel->where('id', $id)->find();
        if (!$paperInfo)
            return $this->error('试卷不存在');

        $paperQuestionsModel = new PaperQuestions();
        $questionIds = $paperQuestionsModel->where('paper_id', $id)->column('question_id');

        if (!$questionIds)
            return $this->error('试题不存在，不能导出');

        $questionModel = new Questions();
        $questionList = $questionModel->whereIn('id', $questionIds)->where('status', 1)
            ->order('type', 'ASC')->select()->toArray();

        if (!$questionList)
            return $this->error('未查询到试题，请查看试题是否发布');

        #组合试题
        foreach ($questionList as $val)
        {
            $exam[$val['type']][] = $val;
        }

        $word = new GenerateWord();
        $url = $word->createWord($exam, $paperInfo->name);

        return $this->success('success', $url);
    }


    private function getSingleQuestions($questionModel, $categoryId = 0 , $courseId = 0, $orgId = 0)
    {
        $singleLevel3 = $questionModel->where('type', 1)->where('difficulty', 3)->where('status', 1);
        if (!in_array($orgId, $this->allAllowOrgIds))
        {
            $singleLevel3 = $singleLevel3->where('org_id', $orgId);
        }
        if ($categoryId > 0) {
            $singleLevel3 = $singleLevel3->where('category_id', $categoryId);
        }
        if ($courseId > 0) {
            $singleLevel3 = $singleLevel3->where('course_id', $courseId);
        }

        $singleLevel3 = $singleLevel3->orderRaw('rand()')->limit(round(self::SINGLE_NUM*0.2))->column('id');

        $singleLevel2 = $questionModel->where('type', 1)->where('difficulty', 2)->where('status', 1);
        if (!in_array($orgId, $this->allAllowOrgIds))
        {
            $singleLevel2 = $singleLevel3->where('org_id', $orgId);
        }
        if ($categoryId > 0) {
            $singleLevel2 = $singleLevel2->where('category_id', $categoryId);
        }
        if ($courseId > 0) {
            $singleLevel2 = $singleLevel2->where('course_id', $courseId);
        }
        $singleLevel2 = $singleLevel2->orderRaw('rand()')->limit(round(self::SINGLE_NUM*0.2))->column('id');

        $singleLevel1 = $questionModel->where('type', 1)->where('difficulty', 1)->where('status', 1);
        if (!in_array($orgId, $this->allAllowOrgIds))
        {
            $singleLevel1 = $singleLevel3->where('org_id', $orgId);
        }
        if ($categoryId > 0) {
            $singleLevel1 = $singleLevel1->where('category_id', $categoryId);
        }
        if ($courseId > 0) {
            $singleLevel1 = $singleLevel1->where('course_id', $courseId);
        }
        $singleLevel1 = $singleLevel1->orderRaw('rand()')->limit(self::SINGLE_NUM-count($singleLevel3)-count($singleLevel2))->column('id');

        return array_merge($singleLevel1, $singleLevel2, $singleLevel3);

    }

    private function getMultipleQuestions($questionModel, $categoryId = 0 , $courseId = 0, $orgId = 0)
    {
        $multipleLevel3 = $questionModel->where('type', 2)->where('difficulty', 3)->where('status', 1);
        if (!in_array($orgId, $this->allAllowOrgIds))
        {
            $multipleLevel3 = $multipleLevel3->where('org_id', $orgId);
        }
        if ($categoryId > 0) {
            $multipleLevel3 = $multipleLevel3->where('category_id', $categoryId);
        }
        if ($courseId > 0) {
            $multipleLevel3 = $multipleLevel3->where('course_id', $courseId);
        }
        $multipleLevel3 = $multipleLevel3->orderRaw('rand()')->limit(round(self::MULTIPLE_NUM*0.2))->column('id');

        $multipleLevel2 = $questionModel->where('type', 2)->where('difficulty', 2)->where('status', 1);
        if (!in_array($orgId, $this->allAllowOrgIds))
        {
            $multipleLevel2 = $multipleLevel2->where('org_id', $orgId);
        }
        if ($categoryId > 0) {
            $multipleLevel2 = $multipleLevel2->where('category_id', $categoryId);
        }
        if ($courseId > 0) {
            $multipleLevel2 = $multipleLevel2->where('course_id', $courseId);
        }
        $multipleLevel2 = $multipleLevel2->orderRaw('rand()')->limit(round(self::MULTIPLE_NUM*0.2))->column('id');

        $multipleLevel1 = $questionModel->where('type', 2)->where('difficulty', 1)->where('status', 1);
        if (!in_array($orgId, $this->allAllowOrgIds))
        {
            $multipleLevel1 = $multipleLevel1->where('org_id', $orgId);
        }
        if ($categoryId > 0) {
            $multipleLevel1 = $multipleLevel1->where('category_id', $categoryId);
        }
        if ($courseId > 0) {
            $multipleLevel1 = $multipleLevel1->where('course_id', $courseId);
        }
        $multipleLevel1 = $multipleLevel1->orderRaw('rand()')->limit(self::MULTIPLE_NUM-count($multipleLevel3)-count($multipleLevel2))->column('id');

        return array_merge($multipleLevel1, $multipleLevel2, $multipleLevel3);
    }

    private function getJudgeQuestions($questionModel, $categoryId = 0 , $courseId = 0, $orgId = 0)
    {
        $JudgeLevel3 = $questionModel->where('type', 3)->where('difficulty', 3)->where('status', 1);
        if (!in_array($orgId, $this->allAllowOrgIds))
        {
            $JudgeLevel3 = $JudgeLevel3->where('org_id', $orgId);
        }
        if ($categoryId > 0) {
            $JudgeLevel3 = $JudgeLevel3->where('category_id', $categoryId);
        }
        if ($courseId > 0) {
            $JudgeLevel3 = $JudgeLevel3->where('course_id', $courseId);
        }
        $JudgeLevel3 = $JudgeLevel3->orderRaw('rand()')->limit(round(self::JUDGE_NUM*0.2))->column('id');

        $JudgeLevel2 = $questionModel->where('type', 3)->where('difficulty', 2)->where('status', 1);
        if (!in_array($orgId, $this->allAllowOrgIds))
        {
            $JudgeLevel2 = $JudgeLevel2->where('org_id', $orgId);
        }
        if ($categoryId > 0) {
            $JudgeLevel2 = $JudgeLevel2->where('category_id', $categoryId);
        }
        if ($courseId > 0) {
            $JudgeLevel2 = $JudgeLevel2->where('course_id', $courseId);
        }
        $JudgeLevel2 = $JudgeLevel2->orderRaw('rand()')->limit(round(self::JUDGE_NUM*0.2))->column('id');

        $JudgeLevel1 = $questionModel->where('type', 3)->where('difficulty', 1)->where('status', 1);
        if (!in_array($orgId, $this->allAllowOrgIds))
        {
            $JudgeLevel1 = $JudgeLevel1->where('org_id', $orgId);
        }
        if ($categoryId > 0) {
            $JudgeLevel1 = $JudgeLevel1->where('category_id', $categoryId);
        }
        if ($courseId > 0) {
            $JudgeLevel1 = $JudgeLevel1->where('course_id', $courseId);
        }
        $JudgeLevel1 = $JudgeLevel1->orderRaw('rand()')->limit(self::JUDGE_NUM-count($JudgeLevel2)-count($JudgeLevel3))->column('id');

        return array_merge($JudgeLevel1, $JudgeLevel2, $JudgeLevel3);
    }

    private function getSubjectQuestions($questionModel, $categoryId = 0 , $courseId = 0, $orgId = 0)
    {
        $subjectLevel = $questionModel->where('type', 4)->where('status', 1);
        if (!in_array($orgId, $this->allAllowOrgIds))
        {
            $subjectLevel = $subjectLevel->where('org_id', $orgId);
        }
        if ($categoryId > 0) {
            $subjectLevel = $subjectLevel->where('category_id', $categoryId);
        }
        if ($courseId > 0) {
            $subjectLevel = $subjectLevel->where('course_id',$courseId);
        }
        $subjectLevel = $subjectLevel->orderRaw('rand()')->limit(self::SUBJECT_NUM)->column('id');

        return $subjectLevel;

    }

}
